#region Copyright Notices
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// 
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endregion

using System;
using System.IO;
using System.Globalization;

namespace Yarr
{
	/// <summary>
	/// A profiler which traces Yarr programs and writes the trace to an XML file
	/// </summary>
	public class XmlTracer : IProfiler
	{
		private TextWriter traceWriter;
        private string filename;

        /// <summary>
        /// Construct an XML tracer that writes trace information to a file
        /// </summary>
        /// <param name="filename">The file to contain trace information</param>
		public XmlTracer(string filename)
		{
            this.filename = filename;
		}

        /// <summary>
        /// Implements IProfiler.Open
        /// </summary>
        public void Open()
        {
            traceWriter = new StreamWriter(filename);
            traceWriter.WriteLine("<?xml version=\"1.0\"?>");
            traceWriter.WriteLine("<trace>");
        }

        /// <summary>
        /// Implements IProfiler.Comment
        /// </summary>
        /// <param name="comment">The comment</param>
        /// <param name="env"></param>
        public void Comment (string comment, Environment env) 
		{
            traceWriter.WriteLine(String.Format(CultureInfo.CurrentCulture, 
                                        "<comment>{0}</comment>", comment));
		}

        /// <summary>
        /// Implements IProfile.Close
        /// </summary>
		public void Close() 
		{
			traceWriter.WriteLine("</trace>");
			traceWriter.Close();
		}

        /// <summary>
        /// Implements IProfile.TraceCall
        /// </summary>
        /// <param name="form">The expression to trace</param>
        /// <param name="env"></param>
        public object TraceCall (object form, Environment env) 
		{
			traceWriter.WriteLine("<eval>");
			traceWriter.WriteLine("<call>{0}</call>",Printer.WriteToString(form));
            return form;
		}

        /// <summary>
        /// Implements IProfile.TracReturn
        /// </summary>
        /// <param name="form">The expression to trace</param>
        /// <param name="env"></param>
        /// <returns>returns its argument</returns>
		public object TraceReturn (object form, Environment env) 
		{
			traceWriter.WriteLine("<return>{0}</return>",Printer.WriteToString(form));
			traceWriter.WriteLine("</eval>");
				
			return form;
		}
	}
}
